package common

import (
	"strings"

	p2putils "hundsun.com/hsl/hschain/p2p/common/utils"

	"hundsun.com/hsl/hschain/common/config"
	"hundsun.com/hsl/hschain/common/util"
	"hundsun.com/hsl/hschain/common/util/pb"
	"hundsun.com/hsl/hschain/p2p/common/constant"
	"hundsun.com/hsl/hschain/p2p/common/p2perror"
)

//P2pConfig p2pConfig
type P2pConfig struct {
	ChainID         string   `yaml:"chainId"`
	Channel         string   `yaml:"channel"` //
	BootstrapPeers  []string `yaml:"bootstrapPeers"`
	ProtectPeers    []string `yaml:"protectPeers"` //受保护的连接节点,为共识时候预留
	ListenAddresses []string `yaml:"listenAddresses"`
	TargetHost      string   `yaml:"targetHost"`
	LogLevel        string   `yaml:"logLevel"`

	P2pPort                   string `yaml:"p2pPort"`
	PeerIDPriKeyPath          string `yaml:"peerIdPriKeyPath"`
	BootIDPubKeyPath          string `yaml:"bootIdPubKeyPath"`
	SeqCenterTimeInterval     int    `yaml:"seqCenterTimeInterval"`     //p2p节点向中心查询周期
	PeerSearchRefreshInterval int    `yaml:"peerSearchRefreshInterval"` //p2p节点搜索刷新秒数
	BroadCastTxMaxWaitTime    int    `yaml:"broadCastTxMaxWaitTime"`    //p2p节点广播交易最大等待时间毫秒数默认50
	BroadCastTxBatchCount     int    `yaml:"broadCastTxBatchCount"`     //p2p节点最大批量广播交易数默认50
	TxVerify                  bool   `yaml:"txVerify"`                  //p2p节点是否验证交易
	EnableIpv6                bool   `yaml:"enableIpv6"`
	EnableNat                 bool   `yaml:"enableNat"`
	EnableBandwidthReporter   bool   `yaml:"enableBandwidthReporter"`
	BroadcastType             int    `yaml:"broadcastType"` //广播类型
}

var p2pConfig *P2pConfig

//InitP2pConfig config初始化
func InitP2pConfig(conf *config.ModuleConfig) *P2pConfig {
	inMap := conf.Parameters
	p2pConfig = &P2pConfig{}

	p2pConfig.ChainID = pb.GetGenesisTransactionPayload().ChainID
	p2pConfig.Channel = inMap["channel"]
	p2pConfig.LogLevel = inMap["logLevel"]
	//拼接address
	p2pConfig.TargetHost = conf.TargetHost
	p2pConfig.P2pPort = inMap["p2pPort"]
	p2pConfig.PeerIDPriKeyPath = inMap["peerIdPriKeyPath"]
	p2pConfig.BootIDPubKeyPath = inMap["bootIdPubKeyPath"]
	if _, ok := inMap["bootstrapPeers"]; ok {
		p2pConfig.BootstrapPeers = strings.Split(inMap["bootstrapPeers"], ",")
		for i := range p2pConfig.BootstrapPeers {
			p2pConfig.BootstrapPeers[i] = strings.TrimSpace(p2pConfig.BootstrapPeers[i])
		}
		//拼接peerid
		for i := range p2pConfig.BootstrapPeers {
			id, _ := p2putils.IDFromPublicKey(p2pConfig.BootIDPubKeyPath)
			p2pConfig.BootstrapPeers[i] = p2pConfig.BootstrapPeers[i] + p2putils.PeerIDEncode(id)
		}
	}
	if _, ok := inMap["protectPeers"]; ok {
		p2pConfig.ProtectPeers = strings.Split(inMap["protectPeers"], ",")
		for i := range p2pConfig.ProtectPeers {
			p2pConfig.ProtectPeers[i] = strings.TrimSpace(p2pConfig.ProtectPeers[i])
		}
	}
	if _, ok := inMap["listenAddresses"]; ok {
		p2pConfig.ListenAddresses = strings.Split(inMap["listenAddresses"], ",")
		for i := range p2pConfig.ListenAddresses {
			p2pConfig.ListenAddresses[i] = strings.TrimSpace(p2pConfig.ListenAddresses[i])
		}
	}
	p2pConfig.SeqCenterTimeInterval = 30                                                       //p2p节点向中心查询周期
	p2pConfig.PeerSearchRefreshInterval = util.Str2int(inMap["peerSearchRefreshInterval"], 60) //p2p节点搜索刷新秒数
	p2pConfig.BroadCastTxMaxWaitTime = util.Str2int(inMap["broadCastTxMaxWaitTime"], constant.BroadCstTxMaxWaitTime)
	p2pConfig.BroadCastTxBatchCount = util.Str2int(inMap["broadCastTxBatchCount"], constant.BroadCstTxBatchCount)
	p2pConfig.TxVerify = false
	if str, ok := inMap["txVerify"]; ok && "true" == str {
		p2pConfig.TxVerify = true
	}
	if str, ok := inMap["enableIpv6"]; ok && "true" == str {
		p2pConfig.EnableIpv6 = true
	}
	if str, ok := inMap["enableNat"]; ok && "true" == str {
		p2pConfig.EnableNat = true
	}
	if str, ok := inMap["enableBandwidthReporter"]; ok && "true" == str {
		p2pConfig.EnableBandwidthReporter = true
	}
	p2pConfig.BroadcastType = util.Str2int(inMap["broadcastType"], 0)
	return p2pConfig
}

//GetConfig 获取配置信息
func GetConfig() (*P2pConfig, error) {
	if p2pConfig == nil {
		return nil, p2perror.Errorf("config not initialized")
	}
	return p2pConfig, nil
}
